package com.evan.petiymanta;

import android.annotation.SuppressLint;
import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Bundle;
import android.os.IBinder;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Toast;

import androidx.annotation.NonNull;
import androidx.core.content.FileProvider;
import androidx.recyclerview.widget.LinearLayoutManager;

import com.bumptech.glide.Glide;
import com.evan.petiymanta.adapter.ProjectAdapter;
import com.evan.petiymanta.base.BaseActivity;
import com.evan.petiymanta.databinding.ActivityMainBinding;
import com.evan.petiymanta.glide.ShizukuModelLoader;
import com.evan.petiymanta.model.BeanFile;
import com.evan.petiymanta.model.ProjectFolder;
import com.evan.petiymanta.service.FileService;
import com.evan.petiymanta.service.FileServiceHolder;
import com.evan.petiymanta.service.IFileExplorerService;
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import com.google.android.material.materialswitch.MaterialSwitch;

import org.w3c.dom.Document;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;

import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.StringReader;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.List;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import rikka.shizuku.Shizuku;

public class MainActivity extends BaseActivity {
    private static final int REQUEST_CODE_PERMISSION = 1001;
    private static final String TAG = "MainActivity";
    private static final String PROJECT_PATH = "/storage/emulated/0/Android/data/com.iapp.app/files/iApp/ProjectApp/";
    private static final String SHIZUKU_PACKAGE = "moe.shizuku.privileged.api";
    private static final String QQ_GROUP_KEY = "TqzsiVkO5HBsSJ_g6zwqZdITBd3kg__1";

    private ActivityMainBinding binding;
    private ProjectAdapter adapter;
    private IFileExplorerService fileService;
    private final ServiceConnection serviceConnection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            try {
                fileService = IFileExplorerService.Stub.asInterface(service);
                FileServiceHolder.setFileService(fileService);

                // 检查权限并加载项目
                if (checkShizukuPermission()) {
                    loadProjects();
                }
            } catch (Exception e) {
                Log.e(TAG, "Service connection failed", e);
                runOnUiThread(() -> {
                    binding.statusText.setText(getString(R.string.status_error, e.getMessage()));
                    Toast.makeText(MainActivity.this, getString(R.string.error_service_connection, e.getMessage()), Toast.LENGTH_LONG).show();
                });
            }
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {
            fileService = null;
            FileServiceHolder.setFileService(null);
            runOnUiThread(() -> {
                binding.statusText.setText(R.string.status_service_disconnected);
                adapter.setProjects(new ArrayList<>());
            });
        }
    };

    // Shizuku 监听器
    private final Shizuku.OnBinderReceivedListener BINDER_RECEIVED_LISTENER = () -> {
        runOnUiThread(() -> {
            if (Shizuku.isPreV11()) {
                binding.statusText.setText(R.string.status_not_supported);
                binding.btnStartShizuku.setVisibility(View.GONE);
                setCardErrorStyle();
            } else {
                binding.statusText.setText(R.string.status_connected);
                binding.btnStartShizuku.setVisibility(View.GONE);
                setCardSuccessStyle();
                checkPermissionAndLoadProjects();
            }
        });
    };

    private final Shizuku.OnBinderDeadListener BINDER_DEAD_LISTENER = () -> {
        runOnUiThread(() -> {
            binding.statusText.setText(R.string.status_disconnected);
            binding.btnStartShizuku.setVisibility(View.VISIBLE);
            setCardErrorStyle();
            adapter.setProjects(new ArrayList<>());
            Toast.makeText(this, R.string.toast_shizuku_disconnected, Toast.LENGTH_LONG).show();
        });
    };

    private final Shizuku.OnRequestPermissionResultListener REQUEST_PERMISSION_RESULT_LISTENER =
            (requestCode, grantResult) -> {
                if (requestCode == REQUEST_CODE_PERMISSION) {
                    if (grantResult == PackageManager.PERMISSION_GRANTED) {
                        binding.statusText.setText(R.string.status_permission_granted);
                        // 权限授予后，重新绑定服务并加载项目
                        bindShizukuService();
                    } else {
                        binding.statusText.setText(R.string.status_permission_denied);
                        Toast.makeText(MainActivity.this, getString(R.string.toast_permission_denied), Toast.LENGTH_LONG).show();
                    }
                }
            };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        binding = ActivityMainBinding.inflate(getLayoutInflater());
        setContentView(binding.getRoot());

        // 设置 Toolbar
        setSupportActionBar(binding.topAppBar);

        setupWindowInsets();

        adapter = new ProjectAdapter(this);
        binding.projectList.setAdapter(adapter);
        binding.projectList.setLayoutManager(new LinearLayoutManager(this));

        // 注册 Shizuku 监听器
        Shizuku.addBinderReceivedListenerSticky(BINDER_RECEIVED_LISTENER);
        Shizuku.addBinderDeadListener(BINDER_DEAD_LISTENER);
        Shizuku.addRequestPermissionResultListener(REQUEST_PERMISSION_RESULT_LISTENER);

        // 检查 Shizuku 权限并绑定服务
        if (checkShizukuPermission()) {
            bindShizukuService();
        }

        // 注册 Glide ModelLoader
        Glide.get(this).getRegistry().prepend(
                String.class,
                ByteBuffer.class,
                new ShizukuModelLoader.Factory()
        );

        // 检查 Shizuku 是否已安装
        if (!isShizukuInstalled()) {
            showInstallShizukuDialog();
        }

        // 设置启动 Shizuku 按钮点击事件
        binding.btnStartShizuku.setOnClickListener(v -> startShizuku());

        // 检查 Shizuku 状态
        updateShizukuStatus();
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        // 停止所有监控
        if (adapter != null) {
            for (ProjectFolder project : adapter.getProjects()) {
                try {
                    fileService.stopMonitoring(project.getPath());
                } catch (Exception e) {
                    Log.e(TAG, "Error stopping monitoring", e);
                }
            }
        }
        // 移除监听器
        Shizuku.removeBinderReceivedListener(BINDER_RECEIVED_LISTENER);
        Shizuku.removeBinderDeadListener(BINDER_DEAD_LISTENER);
        Shizuku.removeRequestPermissionResultListener(REQUEST_PERMISSION_RESULT_LISTENER);
    }

    private boolean checkPermission() {
        if (Shizuku.isPreV11()) {
            binding.statusText.setText(R.string.status_not_supported);
            return false;
        }

        try {
            if (Shizuku.checkSelfPermission() == PackageManager.PERMISSION_GRANTED) {
                return true;
            } else if (Shizuku.shouldShowRequestPermissionRationale()) {
                binding.statusText.setText(R.string.status_permission_denied_permanently);
                return false;
            } else {
                Shizuku.requestPermission(REQUEST_CODE_PERMISSION);
                return false;
            }
        } catch (Throwable e) {
            e.printStackTrace();
            binding.statusText.setText(getString(R.string.status_error, e.getMessage()));
            return false;
        }
    }

    private void checkPermissionAndLoadProjects() {
        if (checkPermission()) {
            // 如果服务未连接，重新绑定服务
            if (fileService == null) {
                bindShizukuService();
            } else {
                loadProjects();
            }
        }
    }

    private void loadProjects() {
        try {
            if (fileService == null) {
                Log.e(TAG, "FileService not connected");
                runOnUiThread(() -> {
                    binding.statusText.setText(R.string.status_service_not_connected);
                    Toast.makeText(this, R.string.toast_service_not_connected, Toast.LENGTH_SHORT).show();
                });
                return;
            }

            runOnUiThread(() -> {
                binding.loadingIndicator.setVisibility(View.VISIBLE);
                binding.statusText.setText(R.string.status_loading);
            });

            // 在后台线程中加载项目
            new Thread(() -> {
                try {
                    List<BeanFile> files = fileService.listFiles(PROJECT_PATH);
                    Log.d(TAG, "Files: " + files);
                    List<ProjectFolder> projects = new ArrayList<>();

                    if (files == null || files.isEmpty()) {
                        runOnUiThread(() -> {
                            binding.loadingIndicator.setVisibility(View.GONE);
                            binding.statusText.setText(R.string.status_no_projects_found);
                            Toast.makeText(this, R.string.toast_no_projects_found, Toast.LENGTH_SHORT).show();
                        });
                        return;
                    }

                    for (BeanFile file : files) {
                        if (file.isDir()) {
                            ProjectFolder project = parseProjectFolder(new File(file.getPath()));
                            if (project != null) {
                                projects.add(project);
                            }
                        }
                    }

                    runOnUiThread(() -> {
                        binding.loadingIndicator.setVisibility(View.GONE);
                        adapter.setProjects(projects);
                        binding.statusText.setText(getString(R.string.status_projects_loaded, projects.size()));

                        // 如果没有找到项目，显示提示
                        if (projects.isEmpty()) {
                            Toast.makeText(this, R.string.toast_no_projects_found, Toast.LENGTH_SHORT).show();
                        }
                    });

                } catch (Exception e) {
                    Log.e(TAG, "Error loading projects", e);
                    runOnUiThread(() -> {
                        binding.loadingIndicator.setVisibility(View.GONE);
                        binding.statusText.setText(getString(R.string.status_error, e.getMessage()));
                        Toast.makeText(this, getString(R.string.error_loading_projects, e.getMessage()), Toast.LENGTH_LONG).show();
                    });
                }
            }).start();

        } catch (Exception e) {
            Log.e(TAG, "Error in loadProjects", e);
            runOnUiThread(() -> {
                binding.loadingIndicator.setVisibility(View.GONE);
                binding.statusText.setText(getString(R.string.status_error, e.getMessage()));
                Toast.makeText(this, getString(R.string.error_loading_projects, e.getMessage()), Toast.LENGTH_LONG).show();
            });
        }
    }

    private ProjectFolder parseProjectFolder(File dir) {
        try {
            String manifestPath = new File(dir, "AndroidManifest.xml").getAbsolutePath();

            if (!fileService.isFileExists(manifestPath)) {
                Log.e(TAG, "清单文件不存在: " + manifestPath);
                return null;
            }

            // 读取文件内容并添加根元素
            String manifestContent = fileService.readFileContent(manifestPath);
            // 移除原有的 XML 声明（如果存在）
            manifestContent = manifestContent.replaceFirst("<\\?xml[^>]*\\?>", "").trim();
            // 包装内容到一个根元素中，并添加 XML 声明
            String wrappedContent = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<manifest>\n"
                    + manifestContent + "\n</manifest>";
            Log.d(TAG, "处理后的清单文件内容: " + wrappedContent);

            ProjectFolder project = new ProjectFolder(dir.getName(), dir.getAbsolutePath());

            // 解析 XML 内容
            DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
            DocumentBuilder builder = factory.newDocumentBuilder();
            Document doc = builder.parse(new InputSource(new StringReader(wrappedContent)));

            // 获取基本信息
            project.setTitle(getXmlValue(doc, "title"));
            project.setVersionName(getXmlValue(doc, "versionName"));
            project.setVersionCode(Integer.parseInt(getXmlValue(doc, "versionint")));
            project.setCreateTime(getXmlValue(doc, "createTime"));
            project.setUpdateTime(getXmlValue(doc, "upTime"));

            // 检查图标文件
            String iconPath = new File(dir, "icon.png").getAbsolutePath();
            if (fileService.isFileExists(iconPath)) {
                project.setIconPath(iconPath);
            }

            return project;
        } catch (Exception e) {
            Log.e(TAG, "解析项目文件夹失败: " + dir.getName(), e);
            e.printStackTrace();
            return null;
        }
    }

    private String getXmlValue(Document doc, String tagName) {
        NodeList nodes = doc.getElementsByTagName(tagName);
        String value = nodes.getLength() > 0 ? nodes.item(0).getTextContent() : "";
        Log.d(TAG, "XML标签 " + tagName + " = " + value);
        return value;
    }

    private boolean checkShizukuPermission() {
        if (!Shizuku.pingBinder()) {
            Log.e(TAG, "Shizuku not available");
            return false;
        }

        try {
            int permission = Shizuku.checkSelfPermission();
            if (permission == PackageManager.PERMISSION_GRANTED) {
                return true;
            } else {
                // 尝试请求权限
                Shizuku.requestPermission(REQUEST_CODE_PERMISSION);
                return false;
            }
        } catch (Exception e) {
            Log.e(TAG, "Error checking Shizuku permission", e);
            return false;
        }
    }

    private void bindShizukuService() {
        try {
            binding.statusText.setText(R.string.status_service_connecting);

            Shizuku.bindUserService(
                    new Shizuku.UserServiceArgs(
                            new ComponentName(BuildConfig.APPLICATION_ID, FileService.class.getName()))
                            .daemon(false)
                            .processNameSuffix("file_service")
                            .version(BuildConfig.VERSION_CODE),
                    serviceConnection
            );
        } catch (Exception e) {
            Log.e(TAG, "Error binding Shizuku service", e);
            binding.statusText.setText(getString(R.string.status_error, e.getMessage()));
            Toast.makeText(this, getString(R.string.error_service_connection, e.getMessage()), Toast.LENGTH_LONG).show();
        }
    }

    @Override
    public boolean onOptionsItemSelected(@NonNull MenuItem item) {
        int itemId = item.getItemId();
        if (itemId == R.id.settings) {
            showSettingsDialog();
            return true;
        } else if (itemId == R.id.more) {
            new MaterialAlertDialogBuilder(this)
                    .setTitle(R.string.dialog_title_disclaimer)
                    .setMessage(R.string.dialog_disclaimer_content)
                    .setPositiveButton(R.string.dialog_button_contact_author, (dialog, which) -> {
                        try {
                            Intent intent = new Intent(Intent.ACTION_SENDTO);
                            intent.setData(Uri.parse("mailto:uyevan@163.com"));
                            intent.putExtra(Intent.EXTRA_SUBJECT, getString(R.string.dialog_email_subject));
                            intent.putExtra(Intent.EXTRA_TEXT, getString(R.string.dialog_message_contact_author));
                            startActivity(intent);
                        } catch (Exception e) {
                            Toast.makeText(this, R.string.error_email_not_supported, Toast.LENGTH_SHORT).show();
                        }
                    })
                    .setNegativeButton(R.string.dialog_button_join_group, (dialog, which) -> joinQQGroup(QQ_GROUP_KEY))
                    .show();
            return true;
        } else if (itemId == R.id.join_group) {
            joinQQGroup(QQ_GROUP_KEY);
            return true;
        }
        return super.onOptionsItemSelected(item);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.top_app_bar, menu);
        return true;
    }

    @SuppressLint("MissingSuperCall")
    @Override
    public void onBackPressed() {
        moveTaskToBack(false);
    }

    private boolean isShizukuInstalled() {
        try {
            getPackageManager().getPackageInfo(SHIZUKU_PACKAGE, 0);
            return true;
        } catch (PackageManager.NameNotFoundException e) {
            return false;
        }
    }

    private void showInstallShizukuDialog() {
        new MaterialAlertDialogBuilder(this)
                .setTitle(R.string.dialog_title_install_shizuku)
                .setMessage(R.string.dialog_message_install_shizuku)
                .setPositiveButton(R.string.dialog_button_install, (dialog, which) -> installShizuku())
                .setNegativeButton(R.string.dialog_button_cancel, (dialog, which) -> finish())
                .setCancelable(false)
                .show();
    }

    private void installShizuku() {
        try {
            binding.loadingIndicator.setVisibility(View.VISIBLE);
            binding.statusText.setText(R.string.status_installing_shizuku);

            File outputFile = new File(getCacheDir(), "shizuku.apk");
            if (outputFile.exists()) {
                outputFile.delete();
            }

            try (InputStream is = getAssets().open("shizuku.apk");
                 OutputStream os = new FileOutputStream(outputFile)) {
                byte[] buffer = new byte[8192];
                int length;
                while ((length = is.read(buffer)) > 0) {
                    os.write(buffer, 0, length);
                }
                os.flush();
            }

            Intent intent = new Intent(Intent.ACTION_VIEW);
            Uri apkUri = FileProvider.getUriForFile(
                    this,
                    BuildConfig.APPLICATION_ID + ".provider",
                    outputFile
            );
            intent.setDataAndType(apkUri, "application/vnd.android.package-archive");
            intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            startActivity(intent);

        } catch (Exception e) {
            Log.e(TAG, "Error installing Shizuku", e);
            Toast.makeText(this, getString(R.string.error_install_shizuku, e.getMessage()), Toast.LENGTH_LONG).show();
            binding.statusText.setText(getString(R.string.status_install_failed, e.getMessage()));
        } finally {
            binding.loadingIndicator.setVisibility(View.GONE);
        }
    }

    private void updateShizukuStatus() {
        if (!Shizuku.pingBinder()) {
            binding.statusText.setText(R.string.status_disconnected);
            binding.btnStartShizuku.setVisibility(View.VISIBLE);
            setCardErrorStyle();
        } else {
            binding.btnStartShizuku.setVisibility(View.GONE);
            if (checkShizukuPermission()) {
                setCardSuccessStyle();
                checkPermissionAndLoadProjects();
            } else {
                setCardErrorStyle();
            }
        }
    }

    private void setCardErrorStyle() {
        binding.statusCard.setCardBackgroundColor(getColor(R.color.error_container));
        binding.statusTitle.setTextColor(getColor(R.color.on_error_container));
        binding.statusText.setTextColor(getColor(R.color.on_error_container));
    }

    private void setCardSuccessStyle() {
        binding.statusCard.setCardBackgroundColor(getColor(R.color.success_container));
        binding.statusTitle.setTextColor(getColor(R.color.on_success_container));
        binding.statusText.setTextColor(getColor(R.color.on_success_container));
    }

    private void startShizuku() {
        try {
            // 尝试启动 Shizuku 应用
            Intent intent = getPackageManager().getLaunchIntentForPackage(SHIZUKU_PACKAGE);
            if (intent != null) {
                startActivity(intent);
            } else {
                // 如果没有安装 Shizuku，显示安装对话框
                showInstallShizukuDialog();
            }
        } catch (Exception e) {
            Log.e(TAG, "Error starting Shizuku", e);
            Toast.makeText(this, getString(R.string.toast_start_shizuku_failed, e.getMessage()), Toast.LENGTH_LONG).show();
        }
    }

    @Override
    protected void onResume() {
        super.onResume();
        // 当应用回到前台时，检查 Shizuku 状态
        updateShizukuStatus();
    }

    /**
     * 发起添加群流程
     *
     * @param key 由QQ群官网生成的key
     * @return 返回true表示呼起手Q成功，返回false表示呼起失败
     */
    private boolean joinQQGroup(String key) {
        Intent intent = new Intent();
        intent.setData(Uri.parse("mqqopensdkapi://bizAgent/qm/qr?url=http%3A%2F%2Fqm.qq.com%2Fcgi-bin%2Fqm%2Fqr%3Ffrom%3Dapp%26p%3Dandroid%26jump_from%3Dwebapi%26k%3D" + key));
        try {
            startActivity(intent);
            return true;
        } catch (Exception e) {
            // 未安装手Q或安装的版本不支持
            Toast.makeText(this, R.string.toast_qq_not_installed, Toast.LENGTH_SHORT).show();
            return false;
        }
    }

    private void showSettingsDialog() {
        View dialogView = getLayoutInflater().inflate(R.layout.dialog_settings, null);
        MaterialSwitch languageSwitch = dialogView.findViewById(R.id.languageSwitch);

        // 设置当前语言状态
        SharedPreferences prefs = getSharedPreferences(Application.PREFS_NAME, MODE_PRIVATE);
        String currentLanguage = prefs.getString(Application.KEY_LANGUAGE, "ug");
        languageSwitch.setChecked(currentLanguage.equals("ug"));

        // 监听语言切换
        languageSwitch.setOnCheckedChangeListener((buttonView, isChecked) -> {
            String newLanguage = isChecked ? "ug" : "zh";
            Application.setLocale(newLanguage);
            // recreate(); // 重新创建活动以应用新语言
            // 重新启动 SplashActivity 以应用更改
            startActivity(SplashActivity.class);
        });

        new MaterialAlertDialogBuilder(this)
                .setView(dialogView)
                .setPositiveButton(R.string.dialog_button_close, null)
                .show();
    }
}